package uebung01;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Aufgabe01 {

	
	/**
	 * ---------
	 * | 1 | 2 |
	 * |--------
	 * | 0 | 3 |
	 * ---------
	 **/

	static int[][] muster = {{1,2},{0,3}};
	
	public static void main(String[] args) {
		try {
			InputStream is = null;
			if (args.length==0) {
				is = Thread.currentThread().getContextClassLoader().getResourceAsStream("res/test2.png"); 
			}
			else {
				is = new FileInputStream(new File(args[0]));
			}
			final BufferedImage bi = ImageIO.read(is);
			final int w = bi.getWidth(), h = bi.getHeight();
			
			int[] pixels = bi.getRGB(0, 0, w, h, new int[w*h], 0, w);
			int[] bayers = bi.getRGB(0, 0, w, h, new int[w*h], 0, w);

			final BufferedImage original = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
			original.setRGB(0, 0, w, h, pixels, 0, w);
			
			for (int i = 0; i<pixels.length; i++) {
				int value = 0;
				int r = (pixels[i]>>16)&0xFF, g = (pixels[i]>>8)&0xFF, b = pixels[i]&0xFF;
				int x = i%w, y = i/w;
				int musterIndexX = x%muster[0].length, musterIndexY = y%muster.length;
				switch(muster[musterIndexY][musterIndexX]) {
					//red
					case 0 :
						value = r; //((r<<16) | 0xFF000000;
						break;
					//green
					case 1 : 
						value = g; //(g<<8) | 0xFF000000;
						break;
					//blue
					case 2 :
						value = b; //b | 0xFF000000;
						break;
					//2nd green
					case 3 : 
						value = g; //(g<<8) | 0xFF000000;
						break;
					default :
						break;
				}
				bayers[i] = value<<16 | value<<8 | value | 0xFF000000;
			}
			
			final BufferedImage grayScaleBayer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
			
			grayScaleBayer.setRGB(0, 0, w, h, bayers, 0, w);
			
			JFrame ff = new JFrame();
			ff.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			JPanel panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
			JScrollPane jsp = new JScrollPane(panel,  JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
			ff.add(jsp);
			panel.add(new JComponent() {
				{setPreferredSize(new Dimension(w,h));}
				@Override
				public void paint(Graphics g) {
					g.drawImage(original, 0, 0, this);
					Graphics2D g2 = (Graphics2D)g;
					g2.setColor(Color.white );
					g2.setFont(Font.decode("SANS-SERIF-BOLD-12"));
					g2.drawString("Original", 10, 20);
					super.paint(g);
				}
			});

			panel.add(new JComponent() {
				{
//					setPreferredSize(new Dimension(w*2,h*2));
					setPreferredSize(new Dimension(w,h));
				}
				@Override
				public void paint(Graphics g) {
//					g.drawImage(grayScaleBayer.getScaledInstance(w*2, h*2, BufferedImage.SCALE_FAST), 0, 0, this);
					g.drawImage(grayScaleBayer, 0, 0, this);
					Graphics2D g2 = (Graphics2D)g;
					g2.setColor(Color.white );
					g2.setFont(Font.decode("SANS-SERIF-BOLD-12"));
					g2.drawString("Bayer Graustufen", 10, 20);

					super.paint(g);
				}
			});
			
			for (int i = 0; i<pixels.length; i++) {
				int r = 0, g = 0, b = 0;
				int value = bayers[i];
				int x = i%w, y = i/w;
				int musterIndexX = x%muster[0].length, musterIndexY = y%muster.length;
				switch(muster[musterIndexY][musterIndexX]) {
					//red
					case 0 : {
						r = value;
						double green = (bayers[(x+1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+w+y*w)%bayers.length]&0xFF);
						g = (int)(green/4.);
						double blue = (bayers[(bayers.length+x-1-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+1+w+y*w)%bayers.length]&0xFF);
						b = (int)(blue/2.);
					}
						break;
					//1st green
					case 1 : {
						g = value;
						double red = (bayers[(bayers.length+x-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+w+y*w)%bayers.length]&0xFF);
						r = (int)(red/2.);
						double blue = (bayers[(bayers.length+x-1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+1+y*w)%bayers.length]&0xFF);
						b = (int)(blue/2.);
					}
						break;
					//blue
					case 2 : {
						b = value;
						double red = (bayers[(x+1+w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-1-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+1-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-1+w+y*w)%bayers.length]&0xFF);
						r = (int)(red/4.);
						double green = (bayers[(x+1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+w+y*w)%bayers.length]&0xFF);
						g = (int)(green/4.);
					}
						break;
					//2nd green
					case 3 : {
						g = value;
						double red = (bayers[(bayers.length+x-1+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+1+y*w)%bayers.length]&0xFF);
						r = (int)(red/2.);
						double blue = (bayers[(bayers.length+x-w+y*w)%bayers.length]&0xFF) + (bayers[(bayers.length+x+w+y*w)%bayers.length]&0xFF);
						b = (int)(blue/2.);
					}
						break;

					default :
						break;
				}
				pixels[i] = (r&0xFF)<<16 | (g&0xFF)<<8 | (b&0xFF) | 0xFF000000;
			}

			bi.setRGB(0, 0, w, h, pixels, 0, w);
			panel.add(new JComponent() {
				{
//					setPreferredSize(new Dimension(w*2,h*2));
					setPreferredSize(new Dimension(w,h));
								}
				@Override
				public void paint(Graphics g) {
//					g.drawImage(bi.getScaledInstance(2*w, 2*h, BufferedImage.SCALE_FAST), 0, 0, this);
					g.drawImage(bi, 0, 0, this);
					Graphics2D g2 = (Graphics2D)g;
					g2.setColor(Color.white );
					g2.setFont(Font.decode("SANS-SERIF-BOLD-12"));
					g2.drawString("Interpolation", 10, 20);

					super.paint(g);
				}
			});
			/**
			try {
				ImageIO.write(bi, "PNG", new File("aufg01out.png"));
			}
			catch (IOException iox) {
				iox.printStackTrace();
			}
			/**/
//			ff.add(panel);

			ff.pack();
			ff.setVisible(true);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
